package com.xxx.sso.service;

import com.xxx.sso.base.BaseService;
import com.xxx.sso.config.RedisService;
import com.xxx.sso.config.SuperAdminProperties;
import com.xxx.sso.consts.RedisConst;
import com.xxx.sso.entity.User;
import com.xxx.sso.enums.ErrEnum;
import com.xxx.sso.repo.UserRepo;
import com.xxx.sso.repo.ref.OnlyPermissionId;
import com.xxx.sso.repo.ref.OnlyRoleId;
import com.xxx.sso.repo.ref.RelRolePermissionRepo;
import com.xxx.sso.repo.ref.RelUserRoleRepo;
import com.xxx.sso.util.HashidsUtil;
import com.xxx.sso.util.Result;
import com.xxx.sso.util.ResultBuilder;
import com.xxx.sso.util.StringUtil;
import com.xxx.sso.vo.UserVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 用户业务层
 * @author caiwl
 * @date 2020/4/30 9:36
 */
@Service
public class UserService extends BaseService<User> {
    @Autowired
    private UserRepo userRepo;
    @Autowired
    private RelUserRoleRepo relUserRoleRepo;
    @Autowired
    private RelRolePermissionRepo rolePermissionRepository;

    @Autowired
    private RedisService redisService;

    public boolean isLogin(String sessionId) {
        String hashId = redisService.get(sessionId);
        Long userId;
        if ((userId = HashidsUtil.decode(hashId)) == 0) {
            return false;
        }
        if (RedisConst.SUPER_ADMIN_ID.equals(userId)) {
            return true;
        }
        return userRepo.existsById(userId);
    }

    public Result login(String sessionId, User user) {
        // TODO 用户密码加密规则
        Optional<User> opt = userRepo.findOne(Example.of(user));
        Long userId;
        if (opt.isPresent()) {
            userId = opt.get().getId();
        }
        else if (isSuperAdmin(user)) {
            userId = RedisConst.SUPER_ADMIN_ID;
        }
        else {
            userId = null;
        }
        if (userId == null) {
            return ResultBuilder.fail(ErrEnum.ERR_CLIENT_LOGIN);
        }
        redisService.set(sessionId, HashidsUtil.encode(userId));
        Map<String, Object> data = new HashMap<>(1);
        data.put("ticket", sessionId);
        return ResultBuilder.okWithMap(data);
    }

    public boolean logout(String token) {
        return redisService.delete(token);
    }

    public UserVO baseInfo(Long id) {
        User user = super.getOne(id);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        List<OnlyRoleId> roleIdList = relUserRoleRepo.findByUserId(id);
        List<Long> roleIds = roleIdList.stream().map(OnlyRoleId::getRoleId).collect(Collectors.toList());
        List<OnlyPermissionId> permissionIdList = rolePermissionRepository.findDistinctByRoleIdIn(roleIds);
        List<Long> permissionIds = permissionIdList.stream().map(OnlyPermissionId::getPermissionId).collect(Collectors.toList());
        userVO.setAuthorities(permissionIds);
        return userVO;
    }

    @Override
    public JpaRepository<User, Long> repository() {
        return userRepo;
    }

    /**
     * 超管检查
     * @param user
     * @return
     */
    @Autowired
    private SuperAdminProperties superAdmin;
    private boolean isSuperAdmin(User user) {
        String usr = superAdmin.getUser();
        String pwd = superAdmin.getPwd();
        if (StringUtil.isEmpty(usr, pwd)) {
            usr = RedisConst.SUPER_ADMIN_USER;
            pwd = RedisConst.SUPER_ADMIN_PWD;
        }
        return usr.equals(user.getUsername()) && pwd.equals(user.getPassword());
    }
}
